package ar.edu.unlam.tpfinal.service.impl;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import ar.edu.unlam.tpfinal.model.Transaction;
import ar.edu.unlam.tpfinal.model.TransactionType;
import ar.edu.unlam.tpfinal.persistence.dao.ClientDAO;
import ar.edu.unlam.tpfinal.persistence.dao.TransactionDAO;
import ar.edu.unlam.tpfinal.persistence.dao.TransactionTypeDAO;
import ar.edu.unlam.tpfinal.result.ProcessResult;
import ar.edu.unlam.tpfinal.service.TransactionTypeService;
import ar.edu.unlam.tpfinal.service.exceptions.ServiceException;
import ar.edu.unlam.tpfinal.struts.forms.TransactionTypeForm;

@Service(value = "transactionTypeService")
public class TransactionTypeServiceImpl implements TransactionTypeService {

	@Autowired
	private TransactionDAO transactionDAO;

	@Autowired
	private ClientDAO clientDAO;

	@Autowired
	private TransactionTypeDAO transactionTypeDAO;

	// DI con Spring
	public void setTransactionDAO(TransactionDAO transactionDAO) {
		this.transactionDAO = transactionDAO;
	}

	public void setClientDAO(ClientDAO clientDAO) {
		this.clientDAO = clientDAO;
	}

	public void setTransactionTypeDAO(TransactionTypeDAO transactionTypeDAO) {
		this.transactionTypeDAO = transactionTypeDAO;
	}

	@Override
	public ProcessResult saveTransactionType(TransactionTypeForm transactionTypeForm) {
		ProcessResult processResult = new ProcessResult();
		try {
			TransactionType transactionType;
			if (transactionTypeForm.getOid() != null && !transactionTypeForm.getOid().equals(Long.valueOf(0))) {
				transactionType = transactionTypeDAO.findByOID(transactionTypeForm.getOid());
				merge(transactionType, transactionTypeForm);
			} else {
				transactionType = getTransactionTypeFromTransactionTypeForm(transactionTypeForm);
			}
			transactionTypeDAO.save(transactionType);
			transactionTypeForm.setOid(transactionType.getOid());
		} catch (Exception e) {
			processResult.addProcessError("No se pudo guardar los cambios", e);
		}
		return processResult;
	}

	private void merge(TransactionType transactionType,	TransactionTypeForm transactionTypeForm) {
		transactionType.setName(transactionTypeForm.getName());
		transactionType.setRequirements(transactionTypeForm.getRequirements());
		transactionType.setComments(transactionTypeForm.getComments());
	}

	@Override
	public ProcessResult deleteTransactionType(TransactionTypeForm transactionTypeForm) {
		ProcessResult processResult = new ProcessResult();
		try {
			TransactionType transactionType = transactionTypeDAO.findByOID(transactionTypeForm.getOid());
			processResult = validateDeleteTransactionType(transactionType);
			if(!processResult.isError()){
				transactionTypeDAO.delete(transactionType);
			}
		} catch (Exception e) {
			processResult.addProcessError("No se pudo borrar el tipo de tramite", e);
		}
		return processResult;
	}

	private ProcessResult validateDeleteTransactionType(
			TransactionType transactionType) {
		ProcessResult processResult = new ProcessResult();
		List<Transaction> transactionList = transactionDAO.getObjectsByProperty(Transaction.TRANSACTION_TYPE, transactionType);
		if(transactionList==null || transactionList.size() > 0){
			processResult.addProcessError("No se puede borrar el tipo de tramite porque hay tramites del mismo en curso", new ServiceException("No se puede borrar el tipo de tramite porque hay tramites del mismo en curso"));
		}
		return processResult;
	}

	@Override
	public List<TransactionTypeForm> listTransactionType() {
		List<TransactionType> transactionTypeList = transactionTypeDAO.findAll();
		List<TransactionTypeForm> transactionTypeFormList = new ArrayList<TransactionTypeForm>();
		for (TransactionType transactionType : transactionTypeList) {
			transactionTypeFormList.add(getTransactionTypeFormFromTransactionType(transactionType));
		}
		return transactionTypeFormList;
	}

	private TransactionType getTransactionTypeFromTransactionTypeForm(TransactionTypeForm transactionTypeForm) {
		TransactionType transactionType = new TransactionType();
		transactionType.setOid(transactionTypeForm.getOid());
		transactionType.setName(transactionTypeForm.getName());
		transactionType.setRequirements(transactionTypeForm.getRequirements());
		transactionType.setComments(transactionTypeForm.getComments());
		return transactionType;
	}

	private TransactionTypeForm getTransactionTypeFormFromTransactionType(TransactionType transactionType) {
		TransactionTypeForm transactionTypeForm = new TransactionTypeForm();
		transactionTypeForm.setOid(transactionType.getOid());
		transactionTypeForm.setName(transactionType.getName());
		transactionTypeForm.setRequirements(transactionType.getRequirements());
		transactionTypeForm.setComments(transactionType.getComments());
		return transactionTypeForm;
	}

	@Override
	public TransactionTypeForm getTransactionTypeByOID(Long oid) {
		TransactionTypeForm transactionTypeForm = getTransactionTypeFormFromTransactionType(transactionTypeDAO.findByOID(oid));
		return transactionTypeForm;
	}

}
